package main

import (
	"distribkv/src/config"
	"distribkv/src/db"
	"distribkv/src/replication"
	"distribkv/src/web"
	"flag"
	"log"
	"net/http"
)

var (
	dbLocation = flag.String("db-location", "", "The path to the bolt db database")
	httpAddr   = flag.String("http-addr", "127.0.0.1:8080", "HTTP host and port")
	configFile = flag.String("config-file", "dbs.toml", "Config file for static database instances")
	instance   = flag.String("instance", "", "The name of the instance for the data")
	replica    = flag.Bool("replica", false, "Whether or not run as a read-only replication")
)

func parseFlags() {
	flag.Parse()

	if *dbLocation == "" {
		log.Fatalf("Must provide db-location")
	}

	if *instance == "" {
		log.Fatalf("Must provide instance")
	}
}

func main() {
	parseFlags()

	c, err := config.ParseFile(*configFile)
	if err != nil {
		log.Fatalf("Error parsing config %q: %v", *configFile, err)
	}

	db_insts, err := config.ParseInstances(c.DistributeInstances, *instance)
	if err != nil {
		log.Fatalf("Error parsing instances config: %v", err)
	}

	log.Printf("Instance count is %d, current instance: %d", db_insts.Count, db_insts.CurIdx)

	db, closeFn, err := db.NewDatabase(*dbLocation, *replica)
	if err != nil {
		log.Fatalf("Error creating %q: %v", *dbLocation, err)
	}

	defer closeFn()

	if *replica {
		leaderAddr, ok := db_insts.Addrs[db_insts.CurIdx]
		if !ok {
			log.Fatalf("Could not find address for primary for instance %d", db_insts.CurIdx)
		}

		go replication.ClientLoop(db, leaderAddr)
	}

	srv := web.NewServer(db, db_insts)

	http.HandleFunc("/get", srv.GetHandler)
	http.HandleFunc("/set", srv.SetHandler)
	http.HandleFunc("/purge", srv.DeleteExtraKeysHandler)
	http.HandleFunc("/next-replication-key", srv.GetNextKeyForReplication)
	http.HandleFunc("/delete-replication-key", srv.DeleyeReplicationKey)

	log.Fatal(http.ListenAndServe(*httpAddr, nil))
}
